package com.database.bean;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

@Entity
@Table(name="USER")
@AttributeOverride( name="id", column = @Column(name="id") )
@XmlRootElement
public class User extends BaseBean{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Column(name="admin", columnDefinition = "BIT", length = 1)
	private boolean admin;
	
	@Size(min=1, max=60)
	@Column(name="nickname", unique = true)
	private String nickname;
	
	@Column(name="password")
	private String password;
	
	@Column(name="email")
	private String email;
	
	@Column(name="salt")
	private String salt;
	
	@Column(name="budget")
	private Double budget=0.0;
	
	@Column(name="imageValue")
	private Double imageValue=0.0;
	
	@Column(name="marketingBudget")
	private Double marketingBudget=0.0;
	
	@Column(name="employerEducationBudget")
	private Double employerEducationBudget=0.0;
	
	@Column(name="rdBudget")
	private Double rdBudget=0.0;
	
	@OneToMany(fetch = FetchType.EAGER, cascade={CascadeType.ALL})
	@Fetch(value = FetchMode.SUBSELECT)
    @JoinColumn(name="companyId")
	private List<CompanyRoundDecisionAndResult>companyRoundDecisionAndResults =new ArrayList<CompanyRoundDecisionAndResult>();
	
	@ManyToOne(fetch = FetchType.EAGER, cascade={CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH})
    @JoinColumn(name="gameId")
	private Game game=null;


	/**
	 * 
	 */
	public User() {
		super();
	}
	
	/**
	 * Helper method for website presentation with stars
	 * @return
	 */
	public int getImageValueStars(){
		int stars=0;
		Long lstars=(long) 0;
		
		if(this.getImageValue()!=null){
			lstars=Math.round(this.getImageValue()*10/2);
			stars=lstars.intValue();
		}
		
		return stars;
	}
	
	/**
	 * 
	 * @return the revenues of all rounds
	 */
	public double getRevenues(){
		double revenue=0;
		
		for(CompanyRoundDecisionAndResult crdar: this.getCompanyRoundDecisionAndResults()){
			if(crdar.getRevenue()!=null){
				revenue = revenue + crdar.getRevenue();
			}
		}
		
		return revenue;
	}
	
	/**
	 * 
	 * @return the expenses of all rounds
	 */
	public double getExpenses(){
		double expenses=0;
		
		for(CompanyRoundDecisionAndResult crdar: this.getCompanyRoundDecisionAndResults()){
			if(crdar.getExpenses()!=null){
				expenses = expenses + crdar.getExpenses();
			}
		}
		
		return expenses;
	}
	
	/**
	 * 
	 * @return the amount of sold products
	 */
	public int getAmountSoldProducts(){
		int amountSold=0;
		
		for(CompanyRoundDecisionAndResult crdar: this.getCompanyRoundDecisionAndResults()){
			amountSold = amountSold + crdar.getAmountSoldProducts();
		}
		
		return amountSold;
	}
	
	/** 
	 * Returns all bought Report Decisions
	 * @return
	 */
	public List<ReportDecision> getAllPreviousMaidReportDecisions(Round actRound, int addition) {
		List<ReportDecision> allRepDec=new ArrayList<ReportDecision>();
		for(CompanyRoundDecisionAndResult crDecRes:this.getCompanyRoundDecisionAndResults()){
			if (actRound != null && ((actRound.getRoundNumber()+addition) > crDecRes.getRound().getRoundNumber())) {
				for (ReportDecision repDec : crDecRes.getReportDecisions()) {
					allRepDec.add(repDec);
				}
			}
		}
		return allRepDec;
	}
	
	/**
	 * @return the budget
	 */
	public Double getBudget() {
		return budget;
	}

	public void addBudget(Double budget) {
		if(this.budget!=null)
			this.budget +=budget;
		else
			this.budget = budget;
	}
	
	public void addMarketingBudget(Double marketingBudget) {
		if(this.marketingBudget!=null)
			this.marketingBudget +=marketingBudget;
		else
			this.marketingBudget = marketingBudget;
	}
	
	public void addEmployerEducationBudgetBudget(Double employerEducationBudget) {
		if(this.employerEducationBudget!=null)
			this.employerEducationBudget +=employerEducationBudget;
		else
			this.employerEducationBudget = employerEducationBudget;
	}
	
	public void addRDBudget(Double rdBudget) {
		if(this.rdBudget!=null)
			this.rdBudget +=rdBudget;
		else
			this.rdBudget = rdBudget;
	}
	
	/**
	 * @param budget the budget to set
	 */
	public void setBudget(Double budget) {
		this.budget = budget;
	}

	/**
	 * @return the imageValue
	 */
	public Double getImageValue() {
		return imageValue;
	}

	/**
	 * @param imageValue the imageValue to set
	 */
	public void setImageValue(Double imageValue) {
		this.imageValue = imageValue;
	}

	/**
	 * @return the marketingBudget
	 */
	public Double getMarketingBudget() {
		return marketingBudget;
	}

	/**
	 * @param marketingBudget the marketingBudget to set
	 */
	public void setMarketingBudget(Double marketingBudget) {
		this.marketingBudget = marketingBudget;
	}

	/**
	 * @return the employerEducationBudget
	 */
	public Double getEmployerEducationBudget() {
		return employerEducationBudget;
	}

	/**
	 * @param employerEducationBudget the employerEducationBudget to set
	 */
	public void setEmployerEducationBudget(Double employerEducationBudget) {
		this.employerEducationBudget = employerEducationBudget;
	}

	/**
	 * @return the rdBudget
	 */
	public Double getRdBudget() {
		return rdBudget;
	}

	/**
	 * @param rdBudget the rdBudget to set
	 */
	public void setRdBudget(Double rdBudget) {
		this.rdBudget = rdBudget;
	}

	/**
	 * @return the companyRoundDecisionAndResults
	 */
	public List<CompanyRoundDecisionAndResult> getCompanyRoundDecisionAndResults() {
		return companyRoundDecisionAndResults;
	}

	/**
	 * @param companyRoundDecisionAndResults the companyRoundDecisionAndResults to set
	 */
	public void setCompanyRoundDecisionAndResults(List<CompanyRoundDecisionAndResult> companyRoundDecisionAndResults) {
		this.companyRoundDecisionAndResults = companyRoundDecisionAndResults;
	}


	/**
	 * @return the trusted
	 */
	public boolean isAdmin() {
		return admin;
	}
	
	public String getTrustedLabel(){
		if(admin){
			return "ja";
		}else{
			return "nein";
		}
	}

	/**
	 * @param trusted the trusted to set
	 */
	public void setAdmin(boolean admin) {
		this.admin = admin;
	}

	/**
	 * @return the nickname
	 */
	public String getNickname() {
		return this.nickname;
	}

	/**
	 * @param nickname the nickname to set
	 */
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	@XmlTransient
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email the email to set
	 */
	public void setEmail(String email) {
		this.email = email;
	}


	/**
	 * @return the salt
	 */
	public String getSalt() {
		return salt;
	}

	public Game getGame() {
		return game;
	}

	public void setGame(Game game) {
		this.game = game;
	}

	/**
	 * @param salt the salt to set
	 */
	@XmlTransient
	public void setSalt(String salt) {
		this.salt = salt;
	}

	@Override
	public String toString() {
		return "User [admin=" + admin
				+ ", nickname=" + nickname + ", password=" + password
				+ ", email=" + email + ", salt=" + salt + "]";
	}
	
	

}
